package com.yiren.dbaa.util;

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


/**
 * 描述 ： 文件压缩解压工具
 */
public class ZipUtils {

    /**
     * TAG to Log
     */
    public static final String TAG = ZipUtils.class.getSimpleName();

    /**
     * 缓存大小
     */
    private static final int BUFF_SIZE = 10 * 1024; // 10K

    /**
     * 缓存大小
     */
    private static final int BUFFER = 4 * 1024;//4K


    /**
     * 解压zip包
     *
     * @param zipFile   zip包路径
     * @param targetDir 解压后文件路径
     * @param isDelete  是否删除原来zip包
     */
    public static String unpackZip(String zipFile, String targetDir, boolean isDelete) {
        String strEntry = null; // 保存每个zip的条目名称
        String temp = null;
        //判断是否有文件分隔符
        if (targetDir.endsWith(File.separator)) {
            temp = targetDir;
        } else {
            temp = targetDir + File.separator;
        }
        try {
            BufferedOutputStream dest = null; // 缓冲输出流
            FileInputStream fis = new FileInputStream(zipFile);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry; // 每个zip条目的实例
            while ((entry = zis.getNextEntry()) != null) {
                try {
                    System.out.println("unpackZip:=" + entry);
                    int count;
                    byte data[] = new byte[BUFFER];
                    strEntry = entry.getName();
                    strEntry = strEntry.replace("\\", File.separator);
                    // File entryFile = new File(targetDir + strEntry);
                    // File entryDir = new File(entryFile.getParent());
                    File entryFile = new File(temp + strEntry);
                    if (!strEntry.contains(".")) {
                        continue;
                    }
                    File entryDir = new File(entryFile.getParent());
                    if (!entryDir.exists()) {
                        boolean mkdirs = entryDir.mkdirs();
                        System.out.println();
                    }
                    FileOutputStream fos = new FileOutputStream(entryFile);
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = zis.read(data, 0, BUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                    dest.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            zis.close();
            fis.close();
            if (isDelete) {
                // 删除zip包
                File file = new File(zipFile);
                file.delete();
                System.out.println("unpackZip:删除zip包成功");
            }
        } catch (Exception cwj) {
            cwj.printStackTrace();
        }
        return strEntry;
    }

    /**
     * 修改文件夹名称
     *
     * @param src
     * @param dest
     * @return
     */
    public static boolean renameToNewFile(String src, String dest) {
        File srcDir = new File(src);
        boolean isOk = srcDir.renameTo(new File(dest));
        System.out.println("renameToNewFile is OK ? :" + isOk);
        return isOk;
    }

    /**
     * 解压缩功能.
     * 将zipFile文件解压到folderPath目录下.
     *
     * @throws Exception
     */
    public static int upZipFile(File zipFile, String folderPath) throws ZipException, IOException {
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
                String dirstr = folderPath + ze.getName();
                dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                Log.d("upZipFile", "str = " + dirstr);
                File f = new File(dirstr);
                f.mkdir();
                continue;
            }
            OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
        return 0;
    }

    /**
     * 给定根目录，返回一个相对路径所对应的实际文件名.
     *
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名，来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    public static File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    substr = new String(substr.getBytes("8859_1"), "GB2312");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                ret = new File(ret, substr);
            }
            if (!ret.exists())
                ret.mkdirs();
            substr = dirs[dirs.length - 1];
            try {
                substr = new String(substr.getBytes("8859_1"), "GB2312");
                Log.d("upZipFile", "substr = " + substr);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret = new File(ret, substr);
            Log.d("upZipFile", "2ret = " + ret);
            return ret;
        }
        return ret;
    }

    /**
     * 批量压缩文件（夹）
     *
     * @param resFileList 要压缩的文件（夹）列表
     * @param zipFile     生成的压缩文件
     * @throws IOException 当压缩过程出错时抛出
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile) throws IOException {
        ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipout, "");
        }
        zipout.close();
    }

    /**
     * 批量压缩文件（夹）
     *
     * @param file    要压缩的文件（夹）列表
     * @param zipFile 生成的压缩文件
     * @throws IOException 当压缩过程出错时抛出
     */
    public static void zipFile(File file, File zipFile) throws IOException {
        ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
        zipFile(file, zipout, "");
        zipout.close();
    }

    /**
     * 批量压缩文件（夹）
     *
     * @param resFileList 要压缩的文件（夹）列表
     * @param zipFile     生成的压缩文件
     * @param comment     压缩文件的注释
     * @throws IOException 当压缩过程出错时抛出
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile, String comment) throws IOException {
        ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipout, "");
        }
        zipout.setComment(comment);
        zipout.close();
    }

    /**
     * 压缩文件（夹）
     *
     * @param resFile  需要压缩的文件（夹）
     * @param zipout   压缩的目的文件
     * @param rootpath 压缩的文件路径
     * @throws FileNotFoundException 找不到文件时抛出
     * @throws IOException           当压缩过程出错时抛出
     */
    public static void zipFile(File resFile, ZipOutputStream zipout, String rootpath) throws FileNotFoundException, IOException {
        rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator) + resFile.getName();
        // rootpath = new String(rootpath.getBytes("8859_1"), "GB2312");
        if (resFile.isDirectory()) {
            File[] fileList = resFile.listFiles();
            for (File file : fileList) {
                zipFile(file, zipout, rootpath);
            }
        } else {
            byte buffer[] = new byte[BUFF_SIZE];
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile), BUFF_SIZE);
            zipout.putNextEntry(new ZipEntry(rootpath));
            int realLength;
            while ((realLength = in.read(buffer)) != -1) {
                zipout.write(buffer, 0, realLength);
            }
            in.close();
            zipout.flush();
            zipout.closeEntry();
        }
    }

    /**
     * 解压文件，忽略文件夹
     *
     * @param zipFile
     * @param targetPath
     * @throws ZipException
     * @throws IOException
     */
    public static void decompressFile(File zipFile, String targetPath) throws ZipException, IOException {
        ZipFile mZipFile = new ZipFile(zipFile);
        @SuppressWarnings("rawtypes")
        Enumeration zipList = mZipFile.entries();
        ZipEntry zipEntry = null;
        byte[] buf = new byte[1024 * 10];
        while (zipList.hasMoreElements()) {
            zipEntry = (ZipEntry) zipList.nextElement();
            if (zipEntry.isDirectory()) {
                continue;
            }
            int position = zipEntry.getName().lastIndexOf("/");
            String fileName = zipEntry.getName().substring(position + 1);
            File file = new File(targetPath, fileName);
            System.out.println("DownloadAsyncTask解压文件:" + targetPath + fileName);
            if (!file.exists()) {
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();//创建目录
                }
                file.createNewFile();//创建文件
            }
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            BufferedInputStream bis = new BufferedInputStream(mZipFile.getInputStream(zipEntry));
            int readLen = 0;
            while ((readLen = bis.read(buf)) != -1) {
                bos.write(buf, 0, readLen);
            }
            bis.close();
            bos.close();
        }
        mZipFile.close();
    }

}
